<html><head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
   <title>20.&nbsp;Remoting and web services using Spring</title><link rel="stylesheet" href="css/stylesheet.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"><link rel="home" href="index.html" title="Reference Documentation"><link rel="up" href="spring-integration.html" title="Part&nbsp;VI.&nbsp;Integration"><link rel="prev" href="spring-integration.html" title="Part&nbsp;VI.&nbsp;Integration"><link rel="next" href="ejb.html" title="21.&nbsp;Enterprise JavaBeans (EJB) integration"><!--Begin Google Analytics code--><script type="text/javascript">
			var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
			document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
		</script><script type="text/javascript">
			var pageTracker = _gat._getTracker("UA-2728886-3");
			pageTracker._setDomainName("none");
			pageTracker._setAllowLinker(true);
			pageTracker._trackPageview();
		</script><!--End Google Analytics code--></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">20.&nbsp;Remoting and web services using Spring</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="spring-integration.html">Prev</a>&nbsp;</td><th width="60%" align="center">Part&nbsp;VI.&nbsp;Integration</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="ejb.html">Next</a></td></tr></table><hr></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="remoting"></a>20.&nbsp;Remoting and web services using Spring</h2></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="remoting-introduction"></a>20.1&nbsp;Introduction</h2></div></div></div><p>Spring features integration classes for remoting support using
    various technologies. The remoting support eases the development of
    remote-enabled services, implemented by your usual (Spring) POJOs.
    Currently, Spring supports the following remoting technologies: </p><div class="itemizedlist"><ul type="disc"><li><p><span class="emphasis"><em>Remote Method Invocation (RMI)</em></span>. Through
          the use of the <code class="classname">RmiProxyFactoryBean</code> and the
          <code class="classname">RmiServiceExporter</code> Spring supports both
          traditional RMI (with <code class="interfacename">java.rmi.Remote</code>
          interfaces and
          <code class="exceptionname">java.rmi.RemoteException</code>) and
          transparent remoting via RMI invokers (with any Java
          interface).</p></li><li><p><span class="emphasis"><em>Spring's HTTP invoker</em></span>. Spring provides a
          special remoting strategy which allows for Java serialization via
          HTTP, supporting any Java interface (just like the RMI invoker). The
          corresponding support classes are
          <code class="classname">HttpInvokerProxyFactoryBean</code> and
          <code class="classname">HttpInvokerServiceExporter</code>.</p></li><li><p><span class="emphasis"><em>Hessian</em></span>. By using Spring's
          <code class="classname">HessianProxyFactoryBean</code> and the
          <code class="classname">HessianServiceExporter</code> you can transparently
          expose your services using the lightweight binary HTTP-based
          protocol provided by Caucho.</p></li><li><p><span class="emphasis"><em>Burlap</em></span>. Burlap is Caucho's XML-based
          alternative to Hessian. Spring provides support classes such as
          <code class="classname">BurlapProxyFactoryBean</code> and
          <code class="classname">BurlapServiceExporter</code>.</p></li><li><p><span class="emphasis"><em>JAX-RPC</em></span>. Spring provides remoting support
          for web services via JAX-RPC (J2EE 1.4's web service API).</p></li><li><p><span class="emphasis"><em>JAX-WS</em></span>. Spring provides remoting support
          for web services via JAX-WS (the successor of JAX-RPC, as introduced
          in Java EE 5 and Java 6).</p></li><li><p><span class="emphasis"><em>JMS</em></span>. Remoting using JMS as the underlying
          protocol is supported via the
          <code class="classname">JmsInvokerServiceExporter</code> and
          <code class="classname">JmsInvokerProxyFactoryBean</code> classes.</p></li></ul></div><p>While discussing the remoting capabilities of Spring, we'll use the
    following domain model and corresponding services:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> Account <span class="hl-keyword">implements</span> Serializable{

    <span class="hl-keyword">private</span> String name;

    <span class="hl-keyword">public</span> String getName(){
        <span class="hl-keyword">return</span> name;
    }

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setName(String name) {
      <span class="hl-keyword">this</span>.name = name;
    }
}</pre><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> AccountService {

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> insertAccount(Account account);

    <span class="hl-keyword">public</span> List&lt;Account&gt; getAccounts(String name);
}</pre><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> RemoteAccountService <span class="hl-keyword">extends</span> Remote {

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> insertAccount(Account account) <span class="hl-keyword">throws</span> RemoteException;

    <span class="hl-keyword">public</span> List&lt;Account&gt; getAccounts(String name) <span class="hl-keyword">throws</span> RemoteException;
}</pre><pre class="programlisting"><span class="hl-comment">// the implementation doing nothing at the moment</span>
<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AccountServiceImpl <span class="hl-keyword">implements</span> AccountService {

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> insertAccount(Account acc) {
        <span class="hl-comment">// do something...</span>
    }
  
    <span class="hl-keyword">public</span> List&lt;Account&gt; getAccounts(String name) {
        <span class="hl-comment">// do something...</span>
    }
}</pre><p>We will start exposing the service to a remote client by using RMI
    and talk a bit about the drawbacks of using RMI. We'll then continue to
    show an example using Hessian as the protocol.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="remoting-rmi"></a>20.2&nbsp;Exposing services using RMI</h2></div></div></div><p>Using Spring's support for RMI, you can transparently expose your
    services through the RMI infrastructure. After having this set up, you
    basically have a configuration similar to remote EJBs, except for the fact
    that there is no standard support for security context propagation or
    remote transaction propagation. Spring does provide hooks for such
    additional invocation context when using the RMI invoker, so you can for
    example plug in security frameworks or custom security credentials
    here.</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-rmi-server"></a>20.2.1&nbsp;Exporting the service using the
      <code class="classname">RmiServiceExporter</code></h3></div></div></div><p>Using the <code class="classname">RmiServiceExporter</code>, we can expose
      the interface of our AccountService object as RMI object. The interface
      can be accessed by using <code class="classname">RmiProxyFactoryBean</code>, or
      via plain RMI in case of a traditional RMI service. The
      <code class="classname">RmiServiceExporter</code> explicitly supports the
      exposing of any non-RMI services via RMI invokers.</p><p>Of course, we first have to set up our service in the Spring
      container:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"accountService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"example.AccountServiceImpl"</span>&gt;
    &lt;<span class="hl-comment">!-- any additional properties, maybe a DAO? --</span>&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Next we'll have to expose our service using the
      <code class="classname">RmiServiceExporter</code>:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.rmi.RmiServiceExporter"</span>&gt;
    &lt;<span class="hl-comment">!-- does not necessarily have to be the same name as the bean to be exported --</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceName"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"AccountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
    &lt;<span class="hl-comment">!-- defaults to 1099 --</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"registryPort"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"1199"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>As you can see, we're overriding the port for the RMI registry.
      Often, your application server also maintains an RMI registry and it is
      wise to not interfere with that one. Furthermore, the service name is
      used to bind the service under. So right now, the service will be bound
      at <code class="literal">'rmi://HOST:1199/AccountService'</code>. We'll use the
      URL later on to link in the service at the client side.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.gif"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>The <code class="literal">servicePort</code> property has been omitted (it
        defaults to 0). This means that an anonymous port will be used to
        communicate with the service.</p></td></tr></table></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-rmi-client"></a>20.2.2&nbsp;Linking in the service at the client</h3></div></div></div><p>Our client is a simple object using the
      <code class="interfacename">AccountService</code> to manage accounts:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> SimpleObject {

    <span class="hl-keyword">private</span> AccountService accountService;

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setAccountService(AccountService accountService) {
        <span class="hl-keyword">this</span>.accountService = accountService;
    }

    <span class="hl-comment">// additional methods using the accountService</span>

}</pre><p>To link in the service on the client, we'll create a separate
      Spring container, containing the simple object and the service linking
      configuration bits:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"example.SimpleObject"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"accountService"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"accountService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.rmi.RmiProxyFactoryBean"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceUrl"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"rmi://HOST:1199/AccountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>That's all we need to do to support the remote account service on
      the client. Spring will transparently create an invoker and remotely
      enable the account service through the
      <code class="classname">RmiServiceExporter</code>. At the client we're linking
      it in using the <code class="classname">RmiProxyFactoryBean</code>.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="remoting-caucho-protocols"></a>20.3&nbsp;Using Hessian or Burlap to remotely call services via HTTP</h2></div></div></div><p>Hessian offers a binary HTTP-based remoting protocol. It is
    developed by Caucho and more information about Hessian itself can be found
    at <a class="ulink" href="http://www.caucho.com" target="_top">http://www.caucho.com</a>.</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-caucho-protocols-hessian"></a>20.3.1&nbsp;Wiring up the <code class="classname">DispatcherServlet</code> for
      Hessian and co.</h3></div></div></div><p>Hessian communicates via HTTP and does so using a custom servlet.
      Using Spring's <code class="classname">DispatcherServlet</code> principles, as
      known from Spring Web MVC usage, you can easily wire up such a servlet
      exposing your services. First we'll have to create a new servlet in your
      application (this is an excerpt from
      <code class="filename">'web.xml'</code>):</p><pre class="programlisting">&lt;<span class="hl-tag">servlet</span>&gt;
    &lt;<span class="hl-tag">servlet-name</span>&gt;remoting&lt;<span class="hl-tag">/servlet-name</span>&gt;
    &lt;<span class="hl-tag">servlet-class</span>&gt;org.springframework.web.servlet.DispatcherServlet&lt;<span class="hl-tag">/servlet-class</span>&gt;
    &lt;<span class="hl-tag">load-on-startup</span>&gt;1&lt;<span class="hl-tag">/load-on-startup</span>&gt;
&lt;<span class="hl-tag">/servlet</span>&gt;

&lt;<span class="hl-tag">servlet-mapping</span>&gt;
    &lt;<span class="hl-tag">servlet-name</span>&gt;remoting&lt;<span class="hl-tag">/servlet-name</span>&gt;
    &lt;<span class="hl-tag">url-pattern</span>&gt;/remoting/*&lt;<span class="hl-tag">/url-pattern</span>&gt;
&lt;<span class="hl-tag">/servlet-mapping</span>&gt;</pre><p>You're probably familiar with Spring's
      <code class="classname">DispatcherServlet</code> principles and if so, you know
      that now you'll have to create a Spring container configuration resource
      named <code class="filename">'remoting-servlet.xml'</code> (after the name of
      your servlet) in the <code class="filename">'WEB-INF'</code>
      directory. The application context will be used in the next
      section.</p><p>Alternatively, consider the use of Spring's simpler
      <code class="classname">HttpRequestHandlerServlet</code>. This allows you to
      embed the remote exporter definitions in your root application context
      (by default in <code class="filename">'WEB-INF/applicationContext.xml'</code>),
      with individual servlet definitions pointing to specific exporter beans.
      Each servlet name needs to match the bean name of its target exporter in
      this case.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-caucho-protocols-hessian-server"></a>20.3.2&nbsp;Exposing your beans by using the
      <code class="classname">HessianServiceExporter</code></h3></div></div></div><p>In the newly created application context called
      <code class="literal">remoting-servlet.xml</code>, we'll create a
      <code class="classname">HessianServiceExporter</code> exporting your
      services:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"accountService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"example.AccountServiceImpl"</span>&gt;
    &lt;<span class="hl-comment">!-- any additional properties, maybe a DAO? --</span>&gt;
&lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">name</span>=<span class="hl-value">"/AccountService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.caucho.HessianServiceExporter"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Now we're ready to link in the service at the client. No explicit
      handler mapping is specified, mapping request URLs onto services, so
      <code class="classname">BeanNameUrlHandlerMapping</code> will be used: Hence,
      the service will be exported at the URL indicated through its bean name
      within the containing <code class="classname">DispatcherServlet</code>'s mapping
      (as defined above):
      <code class="literal">'http://HOST:8080/remoting/AccountService'</code>.</p><p>Alternatively, create a
      <code class="classname">HessianServiceExporter</code> in your root application
      context (e.g. in
      <code class="filename">'WEB-INF/applicationContext.xml'</code>):</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">name</span>=<span class="hl-value">"accountExporter"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.caucho.HessianServiceExporter"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>In the latter case, define a corresponding servlet for this
      exporter in <code class="filename">'web.xml'</code>, with the same end result:
      The exporter getting mapped to the request path
      <code class="literal">/remoting/AccountService</code>. Note that the servlet name
      needs to match the bean name of the target exporter.</p><pre class="programlisting">&lt;<span class="hl-tag">servlet</span>&gt;
    &lt;<span class="hl-tag">servlet-name</span>&gt;accountExporter&lt;<span class="hl-tag">/servlet-name</span>&gt;
    &lt;<span class="hl-tag">servlet-class</span>&gt;org.springframework.web.context.support.HttpRequestHandlerServlet&lt;<span class="hl-tag">/servlet-class</span>&gt;
&lt;<span class="hl-tag">/servlet</span>&gt;

&lt;<span class="hl-tag">servlet-mapping</span>&gt;
    &lt;<span class="hl-tag">servlet-name</span>&gt;accountExporter&lt;<span class="hl-tag">/servlet-name</span>&gt;
    &lt;<span class="hl-tag">url-pattern</span>&gt;/remoting/AccountService&lt;<span class="hl-tag">/url-pattern</span>&gt;
&lt;<span class="hl-tag">/servlet-mapping</span>&gt;</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-caucho-protocols-hessian-client"></a>20.3.3&nbsp;Linking in the service on the client</h3></div></div></div><p>Using the <code class="classname">HessianProxyFactoryBean</code> we can
      link in the service at the client. The same principles apply as with the
      RMI example. We'll create a separate bean factory or application context
      and mention the following beans where the
      <code class="classname">SimpleObject</code> is using the
      <code class="interfacename">AccountService</code> to manage accounts:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"example.SimpleObject"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"accountService"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"accountService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.caucho.HessianProxyFactoryBean"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceUrl"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"http://remotehost:8080/remoting/AccountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-caucho-protocols-burlap"></a>20.3.4&nbsp;Using Burlap</h3></div></div></div><p>We won't discuss Burlap, the XML-based equivalent of Hessian, in
      detail here, since it is configured and set up in exactly the same way
      as the Hessian variant explained above. Just replace the word
      <code class="literal">Hessian</code> with <code class="literal">Burlap</code> and you're all
      set to go.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-caucho-protocols-security"></a>20.3.5&nbsp;Applying HTTP basic authentication to a service exposed through
      Hessian or Burlap</h3></div></div></div><p>One of the advantages of Hessian and Burlap is that we can easily
      apply HTTP basic authentication, because both protocols are HTTP-based.
      Your normal HTTP server security mechanism can easily be applied through
      using the <code class="literal">web.xml</code> security features, for example.
      Usually, you don't use per-user security credentials here, but rather
      shared credentials defined at the
      <code class="literal">Hessian/BurlapProxyFactoryBean</code> level (similar to a
      JDBC <code class="interfacename">DataSource</code>).</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"interceptors"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"authorizationInterceptor"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"authorizationInterceptor"</span> 
      <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"authorizedRoles"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"administrator,operator"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>This is an example where we explicitly mention the
      <code class="classname">BeanNameUrlHandlerMapping</code> and set an interceptor
      allowing only administrators and operators to call the beans mentioned
      in this application context.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.gif"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Of course, this example doesn't show a flexible kind of security
        infrastructure. For more options as far as security is concerned, have
        a look at the Spring Security project at <a class="ulink" href="http://static.springsource.org/spring-security/site/" target="_top">http://static.springsource.org/spring-security/site/</a>.</p></td></tr></table></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="remoting-httpinvoker"></a>20.4&nbsp;Exposing services using HTTP invokers</h2></div></div></div><p>As opposed to Burlap and Hessian, which are both lightweight
    protocols using their own slim serialization mechanisms, Spring HTTP
    invokers use the standard Java serialization mechanism to expose services
    through HTTP. This has a huge advantage if your arguments and return types
    are complex types that cannot be serialized using the serialization
    mechanisms Hessian and Burlap use (refer to the next section for more
    considerations when choosing a remoting technology).</p><p>Under the hood, Spring uses either the standard facilities provided
    by J2SE to perform HTTP calls or Commons
    <code class="classname">HttpClient</code>. Use the latter if you need more
    advanced and easy-to-use functionality. Refer to <a class="ulink" href="http://jakarta.apache.org/commons/httpclient" target="_top">jakarta.apache.org/commons/httpclient</a>
    for more info.</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-httpinvoker-server"></a>20.4.1&nbsp;Exposing the service object</h3></div></div></div><p>Setting up the HTTP invoker infrastructure for a service object
      resembles closely the way you would do the same using Hessian or Burlap.
      Just as Hessian support provides the
      <code class="classname">HessianServiceExporter</code>, Spring's HttpInvoker
      support provides the
      <code class="classname">org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter</code>.</p><p>To expose the <code class="literal">AccountService</code> (mentioned above)
      within a Spring Web MVC <code class="classname">DispatcherServlet</code>, the
      following configuration needs to be in place in the dispatcher's
      application context:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">name</span>=<span class="hl-value">"/AccountService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;
</pre><p>Such an exporter definition will be exposed through the
      <code class="classname">DispatcherServlet</code>'s standard mapping facilities,
      as explained in the section on Hessian.</p><p>Alternatively, create an
      <code class="classname">HttpInvokerServiceExporter</code> in your root
      application context (e.g. in
      <code class="filename">'WEB-INF/applicationContext.xml'</code>):</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">name</span>=<span class="hl-value">"accountExporter"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>In addition, define a corresponding servlet for this exporter in
      <code class="filename">'web.xml'</code>, with the servlet name matching the bean
      name of the target exporter:</p><pre class="programlisting">&lt;<span class="hl-tag">servlet</span>&gt;
    &lt;<span class="hl-tag">servlet-name</span>&gt;accountExporter&lt;<span class="hl-tag">/servlet-name</span>&gt;
    &lt;<span class="hl-tag">servlet-class</span>&gt;org.springframework.web.context.support.HttpRequestHandlerServlet&lt;<span class="hl-tag">/servlet-class</span>&gt;
&lt;<span class="hl-tag">/servlet</span>&gt;

&lt;<span class="hl-tag">servlet-mapping</span>&gt;
    &lt;<span class="hl-tag">servlet-name</span>&gt;accountExporter&lt;<span class="hl-tag">/servlet-name</span>&gt;
    &lt;<span class="hl-tag">url-pattern</span>&gt;/remoting/AccountService&lt;<span class="hl-tag">/url-pattern</span>&gt;
&lt;<span class="hl-tag">/servlet-mapping</span>&gt;</pre><p>If you are running outside of a servlet container and are using
      Sun's Java 6, then you can use the built-in HTTP server implementation.
      You can configure the <code class="classname">SimpleHttpServerFactoryBean</code> together with a
      <code class="classname">SimpleHttpInvokerServiceExporter</code> as is shown in this example:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">name</span>=<span class="hl-value">"accountExporter"</span> 
    <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"httpServer"</span> 
        <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.support.SimpleHttpServerFactoryBean"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"contexts"</span>&gt;
        &lt;<span class="hl-tag">util:map</span>&gt;
            &lt;<span class="hl-tag">entry</span> <span class="hl-attribute">key</span>=<span class="hl-value">"/remoting/AccountService"</span> <span class="hl-attribute">value-ref</span>=<span class="hl-value">"accountExporter"</span>/&gt;
        &lt;<span class="hl-tag">/util:map</span>&gt;
    &lt;<span class="hl-tag">/property</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"port"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"8080"</span> /&gt;
&lt;<span class="hl-tag">/bean</span>&gt;
</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-httpinvoker-client"></a>20.4.2&nbsp;Linking in the service at the client</h3></div></div></div><p>Again, linking in the service from the client much resembles the
      way you would do it when using Hessian or Burlap. Using a proxy, Spring
      will be able to translate your calls to HTTP POST requests to the URL
      pointing to the exported service.</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"httpInvokerProxy"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceUrl"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"http://remotehost:8080/remoting/AccountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;
</pre><p>As mentioned before, you can choose what HTTP client you want to
      use. By default, the <code class="classname">HttpInvokerProxy</code> uses the
      J2SE HTTP functionality, but you can also use the Commons
      <code class="classname">HttpClient</code> by setting the
      <code class="literal">httpInvokerRequestExecutor</code> property:</p><pre class="programlisting">&lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"httpInvokerRequestExecutor"</span>&gt;
    &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor"</span>/&gt;
&lt;<span class="hl-tag">/property</span>&gt;
</pre></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="remoting-web-services"></a>20.5&nbsp;Web services</h2></div></div></div><p>Spring provides full support for standard Java web services
    APIs:</p><div class="itemizedlist"><ul type="disc"><li><p>Exposing web services using JAX-RPC</p></li><li><p>Accessing web services using JAX-RPC</p></li><li><p>Exposing web services using JAX-WS</p></li><li><p>Accessing web services using JAX-WS</p></li></ul></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.gif"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Why two standard Java web services APIs?</p><p>JAX-RPC 1.1 is the standard web service API in J2EE 1.4. As its
      name indicates, it focuses on on RPC bindings, which became less and
      less popular in the past couple of years. As a consequence, it has been
      superseded by JAX-WS 2.0 in Java EE 5, being more flexible in terms of
      bindings but also being heavily annotation-based. JAX-WS 2.1 is also
      included in Java 6 (or more specifically, in Sun's JDK 1.6.0_04 and
      above; previous Sun JDK 1.6.0 releases included JAX-WS 2.0), integrated
      with the JDK's built-in HTTP server.</p><p>Spring can work with both standard Java web services APIs. On Java
      EE 5 / Java 6, the obvious choice is JAX-WS. On J2EE 1.4 environments
      that run on Java 5, you might have the option to plug in a JAX-WS
      provider; check your Java EE server's documentation.</p></td></tr></table></div><p>In addition to stock support for JAX-RPC and JAX-WS in Spring Core,
    the Spring portfolio also features <a class="ulink" href="http://www.springframework.org/spring-ws" target="_top">Spring Web
    Services</a>, a solution for contract-first, document-driven web
    services - highly recommended for building modern, future-proof web
    services.</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-web-services-jaxrpc-export"></a>20.5.1&nbsp;Exposing servlet-based web services using JAX-RPC</h3></div></div></div><p>Spring provides a convenience base class for JAX-RPC servlet
      endpoint implementations -
      <code class="classname">ServletEndpointSupport</code>. To expose our
      <code class="interfacename">AccountService</code> we extend Spring's
      <code class="classname">ServletEndpointSupport</code> class and implement our
      business logic here, usually delegating the call to the business
      layer.</p><pre class="programlisting"><span class="hl-comment">/**
 * JAX-RPC compliant RemoteAccountService implementation that simply delegates
 * to the AccountService implementation in the root web application context.
 *
 * This wrapper class is necessary because JAX-RPC requires working with dedicated
 * endpoint classes. If an existing service needs to be exported, a wrapper that
 * extends ServletEndpointSupport for simple application context access is
 * the simplest JAX-RPC compliant way.
 *
 * This is the class registered with the server-side JAX-RPC implementation.
 * In the case of Axis, this happens in "server-config.wsdd" respectively via
 * deployment calls. The web service engine manages the lifecycle of instances
 * of this class: A Spring application context can just be accessed here.
 */</span><span class="hl-keyword">import</span> org.springframework.remoting.jaxrpc.ServletEndpointSupport;

<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AccountServiceEndpoint <span class="hl-keyword">extends</span> ServletEndpointSupport <span class="hl-keyword">implements</span> RemoteAccountService {
    
    <span class="hl-keyword">private</span> AccountService biz;

    <span class="hl-keyword">protected</span> <span class="hl-keyword">void</span> onInit() {
        <span class="hl-keyword">this</span>.biz = (AccountService) getWebApplicationContext().getBean(<span class="hl-string">"accountService"</span>);
    }

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> insertAccount(Account acc) <span class="hl-keyword">throws</span> RemoteException {
        biz.insertAccount(acc);
    }
  
    <span class="hl-keyword">public</span> Account[] getAccounts(String name) <span class="hl-keyword">throws</span> RemoteException {
        <span class="hl-keyword">return</span> biz.getAccounts(name);
    }
}</pre><p>Our <code class="classname">AccountServletEndpoint</code> needs to run in
      the same web application as the Spring context to allow for access to
      Spring's facilities. In case of Axis, copy the
      <code class="classname">AxisServlet</code> definition into your
      <code class="filename">'web.xml'</code>, and set up the endpoint in
      <code class="filename">'server-config.wsdd'</code> (or use the deploy tool). See
      the sample application JPetStore where the
      <code class="interfacename">OrderService</code> is exposed as a web service
      using Axis.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-web-services-jaxrpc-access"></a>20.5.2&nbsp;Accessing web services using JAX-RPC</h3></div></div></div><p>Spring provides two factory beans to create JAX-RPC web service
      proxies, namely <code class="classname">LocalJaxRpcServiceFactoryBean</code> and
      <code class="classname">JaxRpcPortProxyFactoryBean</code>. The former can only
      return a JAX-RPC service class for us to work with. The latter is the
      full-fledged version that can return a proxy that implements our
      business service interface. In this example we use the latter to create
      a proxy for the <code class="interfacename">AccountService</code> endpoint
      we exposed in the previous section. You will see that Spring has great
      support for web services requiring little coding efforts - most of the
      setup is done in the Spring configuration file as usual:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"accountWebService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.RemoteAccountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"wsdlDocumentUrl"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"http://localhost:8080/account/services/accountService?WSDL"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"namespaceUri"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"http://localhost:8080/account/services/accountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceName"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"AccountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"portName"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"AccountPort"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Where <code class="literal">serviceInterface</code> is our remote business
      interface the clients will use. <code class="literal">wsdlDocumentUrl</code> is
      the URL for the WSDL file. Spring needs this at startup time to create
      the JAX-RPC Service. <code class="literal">namespaceUri</code> corresponds to the
      targetNamespace in the .wsdl file. <code class="literal">serviceName</code>
      corresponds to the service name in the .wsdl file.
      <code class="literal">portName</code> corresponds to the port name in the .wsdl
      file.</p><p>Accessing the web service is now very easy as we have a bean
      factory for it that will expose it as
      <code class="literal">RemoteAccountService</code> interface. We can wire this up
      in Spring:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"client"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"example.AccountClientImpl"</span>&gt;
    ...
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountWebService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>From the client code we can access the web service just as if it
      was a normal class, except that it throws
      <code class="exceptionname">RemoteException</code>.</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AccountClientImpl {

    <span class="hl-keyword">private</span> RemoteAccountService service;
    
    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setService(RemoteAccountService service) {
        <span class="hl-keyword">this</span>.service = service;
    }
    
    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> foo() {
        <span class="hl-keyword">try</span> {
            service.insertAccount(...);
        }
        <span class="hl-keyword">catch</span> (RemoteException ex) {
            <span class="hl-comment">// ouch</span>
        }
    }
}
</pre><p>We can get rid of the checked
      <code class="exceptionname">RemoteException</code> since Spring supports
      automatic conversion to its corresponding unchecked
      <code class="exceptionname">RemoteException</code>. This requires that we
      provide a non-RMI interface also. Our configuration is now:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"accountWebService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"portInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.RemoteAccountService"</span>/&gt;
    ...
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Where <code class="literal">serviceInterface</code> is changed to our non
      RMI interface. Our RMI interface is now defined using the property
      <code class="literal">portInterface</code>. Our client code can now avoid handling
      <code class="exceptionname">java.rmi.RemoteException</code>:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AccountClientImpl {

    <span class="hl-keyword">private</span> AccountService service;
    
    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setService(AccountService service) {
        <span class="hl-keyword">this</span>.service = service;
    }
    
    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> foo() {
        service.insertAccount(...);
    }
}</pre><p>Note that you can also drop the "portInterface" part and specify a
      plain business interface as "serviceInterface". In this case,
      <code class="classname">JaxRpcPortProxyFactoryBean</code> will automatically
      switch to the JAX-RPC "Dynamic Invocation Interface", performing dynamic
      invocations without a fixed port stub. The advantage is that you don't
      even need to have an RMI-compliant Java port interface around (e.g. in
      case of a non-Java target web service); all you need is a matching
      business interface. Check out
      <code class="classname">JaxRpcPortProxyFactoryBean</code>'s javadoc for details
      on the runtime implications.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-web-services-jaxrpc-mapping-registration"></a>20.5.3&nbsp;Registering JAX-RPC Bean Mappings</h3></div></div></div><p>To transfer complex objects over the wire such as
      <code class="classname">Account</code> we must register bean mappings on the
      client side.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.gif"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>On the server side using Axis registering bean mappings is
        usually done in the <code class="filename">'server-config.wsdd'</code>
        file.</p></td></tr></table></div><p>We will use Axis to register bean mappings on the client side. To
      do this we need to register the bean mappings programmatically:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AxisPortProxyFactoryBean <span class="hl-keyword">extends</span> JaxRpcPortProxyFactoryBean {

    <span class="hl-keyword">protected</span> <span class="hl-keyword">void</span> postProcessJaxRpcService(Service service) {
        TypeMappingRegistry registry = service.getTypeMappingRegistry();
        TypeMapping mapping = registry.createTypeMapping();
        registerBeanMapping(mapping, Account.<span class="hl-keyword">class</span>, <span class="hl-string">"Account"</span>);
        registry.register(<span class="hl-string">"http://schemas.xmlsoap.org/soap/encoding/"</span>, mapping);
    }

    <span class="hl-keyword">protected</span> <span class="hl-keyword">void</span> registerBeanMapping(TypeMapping mapping, Class type, String name) {
        QName qName = <span class="hl-keyword">new</span> QName(<span class="hl-string">"http://localhost:8080/account/services/accountService"</span>, name);
        mapping.register(type, qName,
                <span class="hl-keyword">new</span> BeanSerializerFactory(type, qName),
                <span class="hl-keyword">new</span> BeanDeserializerFactory(type, qName));
    }
}</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-web-services-jaxrpc-handler-registration"></a>20.5.4&nbsp;Registering your own JAX-RPC Handler</h3></div></div></div><p>In this section we will register our own
      <code class="interfacename">javax.rpc.xml.handler.Handler</code> to the web
      service proxy where we can do custom code before the SOAP message is
      sent over the wire. The <code class="interfacename">Handler</code> is a
      callback interface. There is a convenience base class provided in
      <code class="filename">jaxrpc.jar</code>, namely
      <code class="classname">javax.rpc.xml.handler.GenericHandler</code> that we will
      extend:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AccountHandler <span class="hl-keyword">extends</span> GenericHandler {

    <span class="hl-keyword">public</span> QName[] getHeaders() {
        <span class="hl-keyword">return</span> null;
    }

    <span class="hl-keyword">public</span> <span class="hl-keyword">boolean</span> handleRequest(MessageContext context) {
        SOAPMessageContext smc = (SOAPMessageContext) context;
        SOAPMessage msg = smc.getMessage();
        <span class="hl-keyword">try</span> {
            SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
            SOAPHeader header = envelope.getHeader();
            ...
        }
        <span class="hl-keyword">catch</span> (SOAPException ex) {
            <span class="hl-keyword">throw</span> <span class="hl-keyword">new</span> JAXRPCException(ex);
        }
        <span class="hl-keyword">return</span> true;
    }
}</pre><p>What we need to do now is to register our AccountHandler to
      JAX-RPC Service so it would invoke
      <code class="methodname">handleRequest(..)</code> before the message is sent
      over the wire. Spring has at this time of writing no declarative support
      for registering handlers, so we must use the programmatic approach.
      However Spring has made it very easy for us to do this as we can
      override the <code class="methodname">postProcessJaxRpcService(..)</code>
      method that is designed for this:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AccountHandlerJaxRpcPortProxyFactoryBean <span class="hl-keyword">extends</span> JaxRpcPortProxyFactoryBean {

    <span class="hl-keyword">protected</span> <span class="hl-keyword">void</span> postProcessJaxRpcService(Service service) {
        QName port = <span class="hl-keyword">new</span> QName(<span class="hl-keyword">this</span>.getNamespaceUri(), <span class="hl-keyword">this</span>.getPortName());
        List list = service.getHandlerRegistry().getHandlerChain(port);
        list.add(<span class="hl-keyword">new</span> HandlerInfo(AccountHandler.<span class="hl-keyword">class</span>, null, null));
        logger.info(<span class="hl-string">"Registered JAX-RPC AccountHandler on port "</span> + port);
    }
}</pre><p>The last thing we must remember to do is to change the Spring
      configuration to use our factory bean:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"accountWebService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"example.AccountHandlerJaxRpcPortProxyFactoryBean"</span>&gt;
    ...
&lt;<span class="hl-tag">/bean</span>&gt;</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-web-services-jaxws-export-servlet"></a>20.5.5&nbsp;Exposing servlet-based web services using JAX-WS</h3></div></div></div><p>Spring provides a convenient base class for JAX-WS servlet
      endpoint implementations -
      <code class="classname">SpringBeanAutowiringSupport</code>. To expose our
      <code class="interfacename">AccountService</code> we extend Spring's
      <code class="classname">SpringBeanAutowiringSupport</code> class and implement
      our business logic here, usually delegating the call to the business
      layer. We'll simply use Spring 2.5's <code class="literal">@Autowired</code>
      annotation for expressing such dependencies on Spring-managed
      beans.</p><pre class="programlisting"><span class="hl-comment">/**
 * JAX-WS compliant AccountService implementation that simply delegates
 * to the AccountService implementation in the root web application context.
 *
 * This wrapper class is necessary because JAX-WS requires working with dedicated
 * endpoint classes. If an existing service needs to be exported, a wrapper that
 * extends SpringBeanAutowiringSupport for simple Spring bean autowiring (through
 * the @Autowired annotation) is the simplest JAX-WS compliant way.
 *
 * This is the class registered with the server-side JAX-WS implementation.
 * In the case of a Java EE 5 server, this would simply be defined as a servlet
 * in web.xml, with the server detecting that this is a JAX-WS endpoint and reacting
 * accordingly. The servlet name usually needs to match the specified WS service name.
 *
 * The web service engine manages the lifecycle of instances of this class.
 * Spring bean references will just be wired in here.
 */</span>
<span class="hl-keyword">import</span> org.springframework.web.context.support.SpringBeanAutowiringSupport;

@WebService(serviceName=<span class="hl-string">"AccountService"</span>)
<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AccountServiceEndpoint <span class="hl-keyword">extends</span> SpringBeanAutowiringSupport {

    @Autowired
    <span class="hl-keyword">private</span> AccountService biz;

    @WebMethod
    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> insertAccount(Account acc) {
       biz.insertAccount(acc);
    }

    @WebMethod
    <span class="hl-keyword">public</span> Account[] getAccounts(String name) {
       <span class="hl-keyword">return</span> biz.getAccounts(name);
    }
}</pre><p>Our <code class="classname">AccountServletEndpoint</code> needs to run in
      the same web application as the Spring context to allow for access to
      Spring's facilities. This is the case by default in Java EE 5
      environments, using the standard contract for JAX-WS servlet endpoint
      deployment. See Java EE 5 web service tutorials for details.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-web-services-jaxws-export-standalone"></a>20.5.6&nbsp;Exporting standalone web services using JAX-WS</h3></div></div></div><p>The built-in JAX-WS provider that comes with Sun's JDK 1.6
      supports exposure of web services using the built-in HTTP server that's
      included in JDK 1.6 as well. Spring's
      <code class="classname">SimpleJaxWsServiceExporter</code> detects all
      <code class="literal">@WebService</code> annotated beans in the Spring application
      context, exporting them through the default JAX-WS server (the JDK 1.6
      HTTP server).</p><p>In this scenario, the endpoint instances are defined and managed
      as Spring beans themselves; they will be registered with the JAX-WS
      engine but their lifecycle will be up to the Spring application context.
      This means that Spring functionality like explicit dependency injection
      may be applied to the endpoint instances. Of course, annotation-driven
      injection through <code class="literal">@Autowired</code> will work as
      well.</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"baseAddress"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"http://localhost:8080/"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"accountServiceEndpoint"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"example.AccountServiceEndpoint"</span>&gt;
    ...
&lt;<span class="hl-tag">/bean</span>&gt;

...</pre><p>The <code class="classname">AccountServiceEndpoint</code> may derive from
      Spring's <code class="classname">SpringBeanAutowiringSupport</code> but doesn't
      have to since the endpoint is a fully Spring-managed bean here. This
      means that the endpoint implementation may look like as follows, without
      any superclass declared - and Spring's <code class="literal">@Autowired</code>
      configuration annotation still being honored:</p><pre class="programlisting">@WebService(serviceName=<span class="hl-string">"AccountService"</span>)
<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AccountServiceEndpoint {

    @Autowired
    <span class="hl-keyword">private</span> AccountService biz;

    @WebMethod
    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> insertAccount(Account acc) {
       biz.insertAccount(acc);
    }

    @WebMethod
    <span class="hl-keyword">public</span> List&lt;Account&gt; getAccounts(String name) {
       <span class="hl-keyword">return</span> biz.getAccounts(name);
    }
}</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-web-services-jaxws-export-ri"></a>20.5.7&nbsp;Exporting web services using the JAX-WS RI's Spring
      support</h3></div></div></div><p>Sun's JAX-WS RI, developed as part of the GlassFish project, ships
      Spring support as part of its JAX-WS Commons project. This allows for
      defining JAX-WS endpoints as Spring-managed beans, similar to the
      standalone mode discussed in the previous section - but this time in a
      Servlet environment. <span class="emphasis"><em>Note that this is not portable in a Java
      EE 5 environment; it is mainly intended for non-EE environments such as
      Tomcat, embedding the JAX-WS RI as part of the web
      application.</em></span></p><p>The difference to the standard style of exporting servlet-based
      endpoints is that the lifecycle of the endpoint instances themselves
      will be managed by Spring here, and that there will be only one JAX-WS
      servlet defined in <code class="literal">web.xml</code>. With the standard Java EE
      5 style (as illustrated above), you'll have one servlet definition per
      service endpoint, with each endpoint typically delegating to Spring
      beans (through the use of <code class="literal">@Autowired</code>, as shown
      above).</p><p>Check out <a class="ulink" href="https://jax-ws-commons.dev.java.net/spring/" target="_top">https://jax-ws-commons.dev.java.net/spring/</a>
      for the details on setup and usage style.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-web-services-jaxws-access"></a>20.5.8&nbsp;Accessing web services using JAX-WS</h3></div></div></div><p>Analogous to the JAX-RPC support, Spring provides two factory
      beans to create JAX-WS web service proxies, namely
      <code class="classname">LocalJaxWsServiceFactoryBean</code> and
      <code class="classname">JaxWsPortProxyFactoryBean</code>. The former can only
      return a JAX-WS service class for us to work with. The latter is the
      full-fledged version that can return a proxy that implements our
      business service interface. In this example we use the latter to create
      a proxy for the <code class="interfacename">AccountService</code> endpoint
      (again):</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"accountWebService"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean"</span>&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"example.AccountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"wsdlDocumentUrl"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"http://localhost:8888/AccountServiceEndpoint?WSDL"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"namespaceUri"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"http://example/"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceName"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"AccountService"</span>/&gt;
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"portName"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"AccountServiceEndpointPort"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>Where <code class="literal">serviceInterface</code> is our business
      interface the clients will use. <code class="literal">wsdlDocumentUrl</code> is
      the URL for the WSDL file. Spring needs this a startup time to create
      the JAX-WS Service. <code class="literal">namespaceUri</code> corresponds to the
      targetNamespace in the .wsdl file. <code class="literal">serviceName</code>
      corresponds to the service name in the .wsdl file.
      <code class="literal">portName</code> corresponds to the port name in the .wsdl
      file.</p><p>Accessing the web service is now very easy as we have a bean
      factory for it that will expose it as <code class="literal">AccountService</code>
      interface. We can wire this up in Spring:</p><pre class="programlisting">&lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"client"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"example.AccountClientImpl"</span>&gt;
    ...
    &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"accountWebService"</span>/&gt;
&lt;<span class="hl-tag">/bean</span>&gt;</pre><p>From the client code we can access the web service just as if it
      was a normal class:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> AccountClientImpl {

    <span class="hl-keyword">private</span> AccountService service;

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setService(AccountService service) {
        <span class="hl-keyword">this</span>.service = service;
    }

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> foo() {
        service.insertAccount(...);
    }
}</pre><p><span class="emphasis"><em>NOTE:</em></span> The above is slightly simplified in
      that JAX-WS requires endpoint interfaces and implementation classes to
      be annotated with <code class="literal">@WebService</code>,
      <code class="literal">@SOAPBinding</code> etc annotations. This means that you
      cannot (easily) use plain Java interfaces and implementation classes as
      JAX-WS endpoint artifacts; you need to annotate them accordingly first.
      Check the JAX-WS documentation for details on those requirements.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="remoting-jms"></a>20.6&nbsp;JMS</h2></div></div></div><p>It is also possible to expose services transparently using JMS as
    the underlying communication protocol. The JMS remoting support in the
    Spring Framework is pretty basic - it sends and receives on the
    <code class="interfacename">same thread</code> and in the <span class="emphasis"><em>same
    non-transactional</em></span> <code class="interfacename">Session</code>, and
    as such throughput will be very implementation dependent. Note that
    these single-threaded and non-transactional constraints apply only to
    Spring's JMS <span class="bold"><strong>remoting</strong></span> support. See
    <a class="xref" href="jms.html" title="22.&nbsp;JMS (Java Message Service)">Chapter&nbsp;22, <i>JMS (Java Message Service)</i></a> for information on Spring's rich support for
    JMS-based <span class="bold"><strong>messaging</strong></span>.</p><p>The following interface is used on both the server and the client
    side.</p><pre class="programlisting"><span class="hl-keyword">package</span> com.foo;

<span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> CheckingAccountService {

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> cancelAccount(Long accountId);
}</pre><p>The following simple implementation of the above interface is used
    on the server-side.</p><pre class="programlisting"><span class="hl-keyword">package</span> com.foo;

<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> SimpleCheckingAccountService <span class="hl-keyword">implements</span> CheckingAccountService {

    <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> cancelAccount(Long accountId) {
        System.out.println(<span class="hl-string">"Cancelling account ["</span> + accountId + <span class="hl-string">"]"</span>);
    }
}</pre><p>This configuration file contains the JMS-infrastructure beans that
    are shared on both the client and server.</p><pre class="programlisting">&lt;<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>&gt;
&lt;<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span>
      <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
      <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"</span>&gt;

    &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"connectionFactory"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.apache.activemq.ActiveMQConnectionFactory"</span>&gt;
        &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"brokerURL"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"tcp://ep-t43:61616"</span>/&gt;
    &lt;<span class="hl-tag">/bean</span>&gt;

    &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"queue"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.apache.activemq.command.ActiveMQQueue"</span>&gt;
        &lt;<span class="hl-tag">constructor-arg</span> <span class="hl-attribute">value</span>=<span class="hl-value">"mmm"</span>/&gt;
    &lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-tag">/beans</span>&gt;</pre><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-jms-server"></a>20.6.1&nbsp;Server-side configuration</h3></div></div></div><p>On the server, you just need to expose the service object using
      the <code class="classname">JmsInvokerServiceExporter</code>.</p><pre class="programlisting">&lt;<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>&gt;
&lt;<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span>
      <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
      <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"</span>&gt;

    &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"checkingAccountService"</span>
          <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.remoting.JmsInvokerServiceExporter"</span>&gt;
        &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"com.foo.CheckingAccountService"</span>/&gt;
        &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span>&gt;
            &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"com.foo.SimpleCheckingAccountService"</span>/&gt;
        &lt;<span class="hl-tag">/property</span>&gt;
   &lt;<span class="hl-tag">/bean</span>&gt;

   &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.listener.SimpleMessageListenerContainer"</span>&gt;
       &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"connectionFactory"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"connectionFactory"</span>/&gt;
       &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"destination"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"queue"</span>/&gt;
       &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"concurrentConsumers"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"3"</span>/&gt;
       &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"messageListener"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"checkingAccountService"</span>/&gt;
   &lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-tag">/beans</span>&gt;</pre><pre class="programlisting"><span class="hl-keyword">package</span> com.foo;

<span class="hl-keyword">import</span> org.springframework.context.support.ClassPathXmlApplicationContext;

<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> Server {

    <span class="hl-keyword">public</span> <span class="hl-keyword">static</span> <span class="hl-keyword">void</span> main(String[] args) <span class="hl-keyword">throws</span> Exception {
        <span class="hl-keyword">new</span> ClassPathXmlApplicationContext(<span class="hl-keyword">new</span> String[]{<span class="hl-string">"com/foo/server.xml"</span>, <span class="hl-string">"com/foo/jms.xml"</span>});
    }
}</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="remoting-jms-client"></a>20.6.2&nbsp;Client-side configuration</h3></div></div></div><p>The client merely needs to create a client-side proxy that will
      implement the agreed upon interface
      (<code class="interfacename">CheckingAccountService</code>). The resulting
      object created off the back of the following bean definition can be
      injected into other client side objects, and the proxy will take care of
      forwarding the call to the server-side object via JMS.</p><pre class="programlisting">&lt;<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>&gt;
&lt;<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span>
      <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
      <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"</span>&gt;

    &lt;<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"checkingAccountService"</span>
          <span class="hl-attribute">class</span>=<span class="hl-value">"org.springframework.jms.remoting.JmsInvokerProxyFactoryBean"</span>&gt;
        &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceInterface"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"com.foo.CheckingAccountService"</span>/&gt;
        &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"connectionFactory"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"connectionFactory"</span>/&gt;
        &lt;<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"queue"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"queue"</span>/&gt;
    &lt;<span class="hl-tag">/bean</span>&gt;

&lt;<span class="hl-tag">/beans</span>&gt;</pre><pre class="programlisting"><span class="hl-keyword">package</span> com.foo;

<span class="hl-keyword">import</span> org.springframework.context.ApplicationContext;
<span class="hl-keyword">import</span> org.springframework.context.support.ClassPathXmlApplicationContext;

<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> Client {

    <span class="hl-keyword">public</span> <span class="hl-keyword">static</span> <span class="hl-keyword">void</span> main(String[] args) <span class="hl-keyword">throws</span> Exception {
        ApplicationContext ctx = <span class="hl-keyword">new</span> ClassPathXmlApplicationContext(
                <span class="hl-keyword">new</span> String[] {<span class="hl-string">"com/foo/client.xml"</span>, <span class="hl-string">"com/foo/jms.xml"</span>});
        CheckingAccountService service = (CheckingAccountService) ctx.getBean(<span class="hl-string">"checkingAccountService"</span>);
        service.cancelAccount(<span class="hl-keyword">new</span> Long(10));
    }
}</pre></div><p>You may also wish to investigate the support provided by the <a class="ulink" href="http://lingo.codehaus.org/" target="_top">Lingo</a> project, which (to quote
    the homepage blurb) &#8220;<span class="quote">
        <span class="emphasis"><em>... is a lightweight POJO based remoting and messaging
        library based on the Spring Framework's remoting libraries which
        extends it to support JMS.</em></span>
      </span>&#8221;</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="remoting-autodection-remote-interfaces"></a>20.7&nbsp;Auto-detection is not implemented for remote interfaces</h2></div></div></div><p>The main reason why auto-detection of implemented interfaces does
    not occur for remote interfaces is to avoid opening too many doors to
    remote callers. The target object might implement internal callback
    interfaces like <code class="interfacename">InitializingBean</code> or
    <code class="interfacename">DisposableBean</code> which one would not want to
    expose to callers.</p><p>Offering a proxy with all interfaces implemented by the target
    usually does not matter in the local case. But when exporting a remote
    service, you should expose a specific service interface, with specific
    operations intended for remote usage. Besides internal callback
    interfaces, the target might implement multiple business interfaces, with
    just one of them intended for remote exposure. For these reasons, we
    <span class="emphasis"><em>require</em></span> such a service interface to be
    specified.</p><p>This is a trade-off between configuration convenience and the risk
    of accidental exposure of internal methods. Always specifying a service
    interface is not too much effort, and puts you on the safe side regarding
    controlled exposure of specific methods.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="remoting-considerations"></a>20.8&nbsp;Considerations when choosing a technology</h2></div></div></div><p>Each and every technology presented here has its drawbacks. You
    should carefully consider your needs, the services you are exposing and the
    objects you'll be sending over the wire when choosing a technology.</p><p>When using RMI, it's not possible to access the objects through the
    HTTP protocol, unless you're tunneling the RMI traffic. RMI is a fairly
    heavy-weight protocol in that it supports full-object serialization which
    is important when using a complex data model that needs serialization over
    the wire. However, RMI-JRMP is tied to Java clients: It is a Java-to-Java
    remoting solution.</p><p>Spring's HTTP invoker is a good choice if you need HTTP-based
    remoting but also rely on Java serialization. It shares the basic
    infrastructure with RMI invokers, just using HTTP as transport. Note that
    HTTP invokers are not only limited to Java-to-Java remoting but also to
    Spring on both the client and server side. (The latter also applies to
    Spring's RMI invoker for non-RMI interfaces.)</p><p>Hessian and/or Burlap might provide significant value when operating
    in a heterogeneous environment, because they explicitly allow for non-Java
    clients. However, non-Java support is still limited. Known issues include
    the serialization of Hibernate objects in combination with
    lazily-initialized collections. If you have such a data model, consider
    using RMI or HTTP invokers instead of Hessian.</p><p>JMS can be useful for providing clusters of services and allowing
    the JMS broker to take care of load balancing, discovery and
    auto-failover. By default: Java serialization is used when using JMS
    remoting but the JMS provider could use a different mechanism for the wire
    formatting, such as XStream to allow servers to be implemented in other
    technologies.</p><p>Last but not least, EJB has an advantage over RMI in that it
    supports standard role-based authentication and authorization and remote
    transaction propagation. It is possible to get RMI invokers or HTTP
    invokers to support security context propagation as well, although this is
    not provided by core Spring: There are just appropriate hooks for plugging
    in third-party or custom solutions here.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="rest-client-access"></a>20.9&nbsp;Accessing RESTful services on the Client</h2></div></div></div><p>The <code class="classname">RestTemplate</code> is the core class for
    client-side access to RESTful services. It is conceptually similar to
    other template classes in Spring, such as
    <code class="classname">JdbcTemplate</code> and <code class="classname">JmsTemplate</code>
    and other template classes found in other Spring portfolio projects.
    <code class="classname">RestTemplate</code>'s behavior is customized by providing
    callback methods and configuring the
    <code class="interfacename">HttpMessageConverter</code> used to marshal
    objects into the HTTP request body and to unmarshal any response back
    into an object. As it is common to use XML as a message format, Spring
    provides a <code class="classname">MarshallingHttpMessageConverter</code> that
    uses the Object-to-XML framework that is part of the
    <code class="classname">org.springframework.oxm</code> package. This gives you a
    wide range of choices of XML to Object mapping technologies to choose
    from.</p><p>This section describes how to use the
    <code class="classname">RestTemplate</code> and its associated
    <code class="interfacename">HttpMessageConverters</code>.</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="rest-resttemplate"></a>20.9.1&nbsp;RestTemplate</h3></div></div></div><p>Invoking RESTful services in Java is typically done using a helper
      class such as Jakarta Commons <code class="classname">HttpClient</code>. For
      common REST operations this approach is too low level as shown
      below.</p><pre class="programlisting">String uri = "http://example.com/hotels/1/bookings";

PostMethod post = new PostMethod(uri);
String request = // create booking request content
post.setRequestEntity(new StringRequestEntity(request));

httpClient.executeMethod(post);

if (HttpStatus.SC_CREATED == post.getStatusCode()) {
  Header location = post.getRequestHeader("Location");
  if (location != null) {
    System.out.println("Created new booking at :" + location.getValue());
  }
}</pre><p>RestTemplate provides higher level methods that correspond to each
      of the six main HTTP methods that make invoking many RESTful services a
      one-liner and enforce REST best practices.</p><div class="table"><a name="d0e37088"></a><p class="title"><b>Table&nbsp;20.1.&nbsp;Overview of RestTemplate methods</b></p><div class="table-contents"><table summary="Overview of RestTemplate methods" style="border-collapse: collapse;border-top: 1.0pt solid ; border-bottom: 1.0pt solid ; border-left: 1.0pt solid ; border-right: 1.0pt solid ; "><colgroup><col><col></colgroup><tbody><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; "><span class="bold"><strong>HTTP Method</strong></span></td><td style="border-bottom: 1.0pt solid ; "><span class="bold"><strong>RestTemplate
              Method</strong></span></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">DELETE</td><td style="border-bottom: 1.0pt solid ; "><a class="ulink" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#delete(String,%20Object...)" target="_top">delete</a></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">GET</td><td style="border-bottom: 1.0pt solid ; "><a class="ulink" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#getForObject(String,%20Class,%20Object...)" target="_top">getForObject</a></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">&nbsp;</td><td style="border-bottom: 1.0pt solid ; "><a class="ulink" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#getForEntity(String,%20Class,%20Object...)" target="_top">getForEntity</a></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">HEAD</td><td style="border-bottom: 1.0pt solid ; "><a class="ulink" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#headForHeaders(String,%20Object...)" target="_top">headForHeaders(String
              url, String&#8230; urlVariables)</a></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">OPTIONS</td><td style="border-bottom: 1.0pt solid ; "><a class="ulink" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#optionsForAllow(String,%20Object...)" target="_top">optionsForAllow(String
              url, String&#8230; urlVariables)</a></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">POST</td><td style="border-bottom: 1.0pt solid ; "><a class="ulink" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#postForLocation(String,%20Object,%20Object...)" target="_top">postForLocation(String
              url, Object request, String&#8230; urlVariables)</a></td></tr><tr><td style="border-right: 1.0pt solid ; border-bottom: 1.0pt solid ; ">&nbsp;</td><td style="border-bottom: 1.0pt solid ; "><a class="ulink" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#postForObject(java.lang.String,%20java.lang.Object,%20java.lang.Class,%20java.lang.String...)" target="_top">postForObject(String
				  url, Object request, Class&lt;T&gt; responseType, String&#8230;
				  uriVariables)</a></td></tr><tr><td style="border-right: 1.0pt solid ; ">PUT</td><td style=""><a class="ulink" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#put(String,%20Object,%20Object...)" target="_top">put(String
              url, Object request, String&#8230;urlVariables)</a></td></tr></tbody></table></div></div><br class="table-break"><p>The names of <code class="classname">RestTemplate</code> methods follow a
      naming convention, the first part indicates what HTTP method is being
      invoked and the second part indicates what is returned. For example, the
      method <code class="methodname">getForObject()</code> will perform a GET, convert
      the HTTP response into an object type of your choice and return that
      object. The method <code class="methodname">postForLocation()</code> will do a
      POST, converting the given object into a HTTP request and return the
      response HTTP Location header where the newly created object can be
      found. In case of an exception processing the HTTP request, an exception
      of the type <code class="classname">RestClientException</code> will be
      thrown; this behavior can be changed by plugging in another <code class="interfacename">ResponseErrorHandler</code>
	  implementation into the <code class="classname">RestTemplate</code>.</p><p>Objects passed to and returned from these methods are converted to
      and from HTTP messages by
      <code class="interfacename">HttpMessageConverter</code> instances.
      Converters for the main mime types are registered by default, but you
      can also write your own converter and register it via the
      <code class="methodname">messageConverters()</code> bean property. The default
      converter instances registered with the template are
      <code class="classname">ByteArrayHttpMessageConverter</code>,
      <code class="classname">StringHttpMessageConverter</code>,
      <code class="classname">FormHttpMessageConverter</code> and
      <code class="classname">SourceHttpMessageConverter</code>. You can override
      these defaults using the <code class="methodname">messageConverters()</code> bean
      property as would be required if using the
      <code class="classname">MarshallingHttpMessageConverter</code> or 
      <code class="classname">MappingJacksonHttpMessageConverter</code>.</p><p>Each method takes URI template arguments in two forms, either as a
      <code class="literal">String</code> variable length argument or a
      <code class="literal">Map&lt;String,String&gt;</code>. For example,</p><pre class="programlisting">String result = restTemplate.getForObject(<span class="hl-string">"http://example.com/hotels/{hotel}/bookings/{booking}"</span>,
                                          String.<span class="hl-keyword">class</span>,<span class="hl-string">"42"</span>, <span class="hl-string">"21"</span>);
</pre><p>using variable length arguments and</p><pre class="programlisting">Map&lt;String, String&gt; vars = Collections.singletonMap(<span class="hl-string">"hotel"</span>, <span class="hl-string">"42"</span>);
String result =
  restTemplate.getForObject(<span class="hl-string">"http://example.com/hotels/{hotel}/rooms/{hotel}"</span>, String.<span class="hl-keyword">class</span>, vars);
</pre><p>using a <code class="literal">Map&lt;String,String&gt;</code>.</p><p>To create an instance of <code class="classname">RestTemplate</code> you can
      simply call the default no-arg constructor. This will use standard Java
      classes from the <code class="literal">java.net</code> package as the underlying
      implementation to create HTTP requests. This can be overridden by
      specifying an implementation of
      <code class="interfacename">ClientHttpRequestFactory</code>. Spring provides
      the implementation
      <code class="classname">CommonsClientHttpRequestFactory</code> that uses the
      Jakarta Commons <code class="classname">HttpClient</code> to create requests.
      <code class="classname">CommonsClientHttpRequestFactory</code> is configured
      using an instance of
      <code class="classname">org.apache.commons.httpclient.HttpClient</code> which
      can in turn be configured with credentials information or connection
      pooling functionality.</p><p>The previous example using Jakarta Commons
      <code class="classname">HttpClient</code> directly rewritten to use the
      <code class="classname">RestTemplate</code> is shown below</p><pre class="programlisting">uri = "http://example.com/hotels/{id}/bookings";

RestTemplate template = new RestTemplate();

Booking booking = // create booking object

URI location = template.postForLocation(uri, booking, "1");
</pre><p>The general callback interface is
      <code class="interfacename">RequestCallback</code> and is called when the
      execute method is invoked.</p><pre class="programlisting"><span class="hl-keyword">public</span> &lt;T&gt; T execute(String url, HttpMethod method, RequestCallback requestCallback,
                     ResponseExtractor&lt;T&gt; responseExtractor,
                     String... urlVariables)


<span class="hl-comment">// also has an overload with urlVariables as a Map&lt;String, String&gt;.</span></pre><p>The <code class="interfacename">RequestCallback</code> interface is
      defined as</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> RequestCallback {
 <span class="hl-keyword">void</span> doWithRequest(ClientHttpRequest request) <span class="hl-keyword">throws</span> IOException;
}</pre><p>and allows you to manipulate the request headers and write to the
      request body. When using the execute method you do not have to worry
      about any resource management, the template will always close the
      request and handle any errors. Refer to the API documentation for more
      information on using the execute method and the meaning of its other
      method arguments.</p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="d0e37263"></a>20.9.1.1&nbsp;Dealing with request and response headers</h4></div></div></div><p>Besides the methods described above, the <code class="classname">RestTemplate</code>
        also has the <code class="methodname">exchange()</code> method, which can be
        used for arbitrary HTTP method execution based on the <code class="classname">HttpEntity</code>
        class.</p><p>Perhaps most importantly, the <code class="methodname">exchange()</code> 
        method can be used to add request headers and read response headers.
        For example:</p><pre class="programlisting">HttpHeaders requestHeaders = <span class="hl-keyword">new</span> HttpHeaders();
requestHeaders.set(<span class="hl-string">"MyRequestHeader"</span>, <span class="hl-string">"MyValue"</span>);
HttpEntity&lt;?&gt; requestEntity = <span class="hl-keyword">new</span> HttpEntity(requestHeaders);

HttpEntity&lt;String&gt; response = template.exchange(<span class="hl-string">"http://example.com/hotels/{hotel}"</span>,
  HttpMethod.GET, requestEntity, String.<span class="hl-keyword">class</span>, <span class="hl-string">"42"</span>);

String responseHeader = response.getHeaders().getFirst(<span class="hl-string">"MyResponseHeader"</span>);
String body = response.getBody();</pre><p>In the above example, we first prepare a request entity that contains the
        <code class="literal">MyRequestHeader</code> header. We then retrieve the response, and
        read the <code class="literal">MyResponseHeader</code> and body.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="rest-message-conversion"></a>20.9.2&nbsp;HTTP Message Conversion</h3></div></div></div><p>Objects passed to and returned from the methods
      <code class="methodname">getForObject()</code>,
      <code class="methodname">postForLocation()</code>, and
      <code class="methodname">put()</code> are converted to HTTP requests and from
      HTTP responses by <code class="interfacename">HttpMessageConverters</code>.
      The <code class="interfacename">HttpMessageConverter</code> interface is
      shown below to give you a better feel for its functionality</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> HttpMessageConverter&lt;T&gt; {

      <span class="hl-comment">// Indicate whether the given class and media type can be read by this converter.</span>
      <span class="hl-keyword">boolean</span> canRead(Class&lt;?&gt; clazz, MediaType mediaType);

      <span class="hl-comment">// Indicate whether the given class and media type can be written by this converter.</span>
      <span class="hl-keyword">boolean</span> canWrite(Class&lt;?&gt; clazz, MediaType mediaType);

      <span class="hl-comment">// Return the list of MediaType objects supported by this converter.</span>
      List&lt;MediaType&gt; getSupportedMediaTypes();

      <span class="hl-comment">// Read an object of the given type from the given input message, and returns it.</span>
      T read(Class&lt;T&gt; clazz, HttpInputMessage inputMessage) <span class="hl-keyword">throws</span> IOException,
                                                                   HttpMessageNotReadableException;

      <span class="hl-comment">// Write an given object to the given output message.</span>
      <span class="hl-keyword">void</span> write(T t, HttpOutputMessage outputMessage) <span class="hl-keyword">throws</span> IOException,
                                                              HttpMessageNotWritableException;

    }</pre><p>Concrete implementations for the main media (mime) types are
      provided in the framework and are registered by default with the
      <code class="classname">RestTemplate</code> on the client-side and with
      <code class="classname">AnnotationMethodHandlerAdapter</code> on the
      server-side.</p><p>The implementations of
      <code class="classname">HttpMessageConverter</code>s are described in the
      following sections. For all converters a default media type is used but
      can be overridden by setting the
      <code class="classname">supportedMediaTypes</code> bean property</p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="rest-string-converter"></a>20.9.2.1&nbsp;StringHttpMessageConverter</h4></div></div></div><p>An <code class="interfacename">HttpMessageConverter</code>
        implementation that can read and write Strings from the HTTP request
        and response. By default, this converter supports all text media types
        (<code class="literal">text/*</code>), and writes with a
        <code class="literal">Content-Type</code> of
        <code class="literal">text/plain</code>.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="rest-form-converter"></a>20.9.2.2&nbsp;FormHttpMessageConverter</h4></div></div></div><p>An <code class="interfacename">HttpMessageConverter</code>
        implementation that can read and write form data from the HTTP request
        and response. By default, this converter reads and writes the media
        type <code class="literal">application/x-www-form-urlencoded</code>. Form data
        is read from and written into a <code class="literal">MultiValueMap&lt;String,
        String&gt;</code>.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="rest-byte-converter"></a>20.9.2.3&nbsp;ByteArrayMessageConverter</h4></div></div></div><p>An <code class="interfacename">HttpMessageConverter</code>
        implementation that can read and write byte arrays from the HTTP
        request and response. By default, this converter supports all media
        types (<code class="literal">*/*</code>), and writes with a
        <code class="literal">Content-Type</code> of
        <code class="literal">application/octet-stream</code>. This can be overridden by
        setting the <span class="property">supportedMediaTypes</span> property, and
        overriding <code class="literal">getContentType(byte[])</code>.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="rest-marhsalling-converter"></a>20.9.2.4&nbsp;MarshallingHttpMessageConverter</h4></div></div></div><p>An <code class="interfacename">HttpMessageConverter</code>
        implementation that can read and write XML using Spring's
        <code class="interfacename">Marshaller</code> and
        <code class="interfacename">Unmarshaller</code> abstractions from the
        <code class="classname">org.springframework.oxm</code> package. This converter
        requires a <code class="interfacename">Marshaller</code> and
        <code class="interfacename">Unmarshaller</code> before it can be used.
        These can be injected via constructor or bean properties. By default
        this converter supports (<code class="literal">text/xml</code>) and
        (<code class="literal">application/xml</code>).</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="rest-mapping-json-converter"></a>20.9.2.5&nbsp;MappingJacksonHttpMessageConverter</h4></div></div></div><p>An <code class="interfacename">HttpMessageConverter</code> 
        implementation that can read and write JSON using Jackson's 
        <code class="interfacename">ObjectMapper</code>. JSON mapping can be 
        customized as needed through the use of Jackson's provided annotations. When 
        further control is needed, a custom 
        <code class="interfacename">ObjectMapper</code> can be injected through 
        the <code class="literal">ObjectMapper</code> property for cases where custom 
        JSON serializers/deserializers need to be provided for specific types. 
        By default this converter supports (<code class="literal">application/json</code>).</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="rest-source-converter"></a>20.9.2.6&nbsp;SourceHttpMessageConverter</h4></div></div></div><p>An <code class="interfacename">HttpMessageConverter</code>
        implementation that can read and write
        <code class="classname">javax.xml.transform.Source</code> from the HTTP
        request and response. Only <code class="classname">DOMSource</code>,
        <code class="classname">SAXSource</code>, and
        <code class="classname">StreamSource</code> are supported. By default, this
        converter supports (<code class="literal">text/xml</code>) and
        (<code class="literal">application/xml</code>).</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="rest-buffered-image-converter"></a>20.9.2.7&nbsp;BufferedImageHttpMessageConverter</h4></div></div></div><p>An <code class="interfacename">HttpMessageConverter</code>
        implementation that can read and write
        <code class="classname">java.awt.image.BufferedImage</code> from the HTTP
        request and response. This converter reads and writes the media type
        supported by the Java I/O API.</p></div></div></div></div><!--Begin LoopFuse code--><script src="http://loopfuse.net/webrecorder/js/listen.js" type="text/javascript"></script><script type="text/javascript">
			_lf_cid = "LF_48be82fa";
			_lf_remora();
		</script><!--End LoopFuse code--><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spring-integration.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="spring-integration.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="ejb.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part&nbsp;VI.&nbsp;Integration&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;21.&nbsp;Enterprise JavaBeans (EJB) integration</td></tr></table></div></body></html>